%    Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000 Aladdin Enterprises.  All rights reserved.
% 
% This software is provided AS-IS with no warranty, either express or
% implied.
% 
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
% 
% For more information about licensing, please refer to
% http://www.ghostscript.com/licensing/. For information on
% commercial licensing, go to http://www.artifex.com/licensing/ or
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
% San Rafael, CA  94903, U.S.A., +1(415)492-9861.

% $Id: gs_ciddc.ps,v 1.14 2005/01/20 00:26:06 ray Exp $
% Define Decoding and CIDDecoding resource categories and related procsets.

languagelevel 2 .setlanguagelevel
currentglobal true setglobal

%----------------ParseDecoding procset----------------------------

/ParseDecoding <<

/Parse    % <resource_name> <num_tokens> Parse -
{ dict begin                                  % /ResName
  0                                           % /ResName nCode
  { currentfile token not {
      exit
    } if                                      % /ResName nCode token
    dup type /integertype eq {                % /ResName nCode
       exch pop
    } {
      1 index def                             % /ResName nCode
    } ifelse
  } loop                                      % /ResName nCode
  pop                                         % /ResName
  currentdict end /Decoding                   % /ResName <<inst>> /Decoding
  defineresource pop
} bind

>> /ProcSet defineresource pop

%----------------Decoding category----------------------------

/Generic /Category findresource dup length dict copy
dup /InstanceType /dicttype put
/Decoding exch /Category defineresource pop

%----------------ParseCMap_Inverse procset----------------------------

/ParseCMap_Inverse <<
  /findresource { pop } bind
  /defineresource { pop pop } bind
  /dict {}
  /def { pop pop } bind
  /dup null
  /begin { pop } bind
  /end {}
  /currentdict null
  /CMapName null
  /usecmap { pop } bind
  /begincmap {}
  /endcmap {}
  /begincodespacerange { pop mark } bind
  /endcodespacerange { cleartomark } bind
  /beginnotdefrange { pop mark } bind
  /endnotdefrange { cleartomark } bind
  /beginbfchar { pop mark } bind
  /endbfchar { pop mark } bind
  /beginbfrange { begincidrange }
  /endbfrange { endcidrange }
  /begincidchar { beginbfchar }
  /endcidchar { endbfchar }
  /begincidrange { pop mark } bind
  /endcidrange  { cleartomark } bind
>>  % Just keep it on stack for a while.

% Now we define another dict for local binding, than merge it with the previous one :
dup length 5 add dict begin

  /.Ranges 40 dict def % Key = CID/256, value = array of 256 integer codes.
  //.Ranges /CIDCount 0 put

  /.StringToInt     % <string> .StringToInt <integer>
  { 0 exch { exch 8 bitshift add } forall
  } bind def

  /.SetCouple    % <I> <b> .SetCouple -
  { exch                                    % b I
    dup 256 idiv                            % b I I0
    dup //.Ranges exch known not {
      dup //.Ranges exch 256 array put
    } if                                    % b I I0
    //.Ranges exch get                      % b I [Range]
    exch 256 mod                            % b [Range] I1
    3 2 roll put                            %
  } bind def

  /endcidrange
  { % Writes the inversed CMap to .Ranges
    counttomark 3 idiv {                    % (b) (e) I
      exch .StringToInt                     % (b) I e
      3 2 roll .StringToInt                 % I e b
      % Note : this code does't handle multidimentional CID ranges.
      % fixme : optimize below.
      dup 3 2 roll exch sub 1 add           % I b d
      { 2 copy //.SetCouple exec            % I b
        1 add exch 1 add exch
      } repeat                              % I b
      pop                                   % I
      dup //.Ranges /CIDCount get gt {      % I
        dup //.Ranges exch /CIDCount exch put
      } if                                  % I
      pop
    } repeat
    pop % mark
  } bind def

  /.GetCIDDecoding         % - .GetCIDDEcoding <dict>
  { //.Ranges dup length dict copy
    //.Ranges //.PurgeDict exec
    //.Ranges /CIDCount 0 put
  } bind def

currentdict end
exch copy % Merge the dicts - see above.
/ProcSet defineresource pop

%----------------CIDDecoding category----------------------------
% Note that we put all instances in global memory - see FindResource.

/Generic /Category findresource dup length dict copy
begin
  /Category /CIDDecoding def
  /InstanceType /dicttype def

  /.CMapChooser <<
    % This lists CMaps to inverse and unite for creating a CIDDecoding.
    % Choose by FAPIcidfmap.Registry concatenated with TrueType encoding ID.
    % Font renderer must provide the glyph substitution internally.

    /CNS1.Big5       [ /ETen-B5-H /ETen-B5-V ]
    /CNS1.Unicode    [ /UniCNS-UCS2-H /UniCNS-UCS2-V]
    /GB1.GB2312      [ /GBK-EUC-H /GBK-EUC-V ]
    /GB1.Unicode     [ /UniGB-UCS2-H /UniGB-UCS2-V ]
    /Japan1.ShiftJIS [ /90ms-RKSJ-H /90ms-RKSJ-V ]
    /Japan1.Unicode  [ /UniJIS-UCS2-H  /UniJIS-UCS2-V]
    /Japan2.ShiftJIS [ /90ms-RKSJ-H /90ms-RKSJ-V ]
    /Japan2.Unicode  [ /UniHojo-UCS2-H ]
    /Korea1.Johab    [ /KSC-Johab-V /KSC-Johab-H ]
    /Korea1.Wansung  [ /KSCms-UHC-V /KSCms-UHC-H ]
    /Korea1.Unicode  [ /UniKS-UCS2-H /UniKS-UCS2-V ]
    /Identity.Symbol [ /Identity-H /Identity-V ]
  >> def

  /.MakeInstance    % <name> .MakeInstance <inst>
  { dup                                              % /Name /Name
    //.CMapChooser exch .knownget not {
      (Can't build /) print =string cvs print ( /CIDDecoding resource. See gs_ciddc.ps . ) =
      /findresource cvx /undefinedresource signalerror
    } if                                             % /Name [CMaps]
    exch pop                                         % [CMaps]
    /CMap /Category findresource                     % [CMaps] <CMapCategory>
    /ParseCMap_Inverse /ProcSet findresource         % [CMaps] <CMapCategory> <PCI>
    3 2 roll {                                       % <CMapCategory> <PCI> /CMapName
      3 2 roll begin                                 % <PCI> /CMapName
      dup .ResourceFile not {
        (Can't find CMap ) print =string cvs print ( building a CIDDecoding resource. ) =
        /findresource cvx /undefinedresource signalerror
      } if
      currentdict end exch                           % <PCI> /CMapName <CMapCategory> file

      3 index begin
      cvx exec                                       % <PCI> /CMapName <CMapCategory>
      end
      exch pop exch                                  % <CMapCategory> <PCI>
    } forall
    exch pop begin                                   %
    .GetCIDDecoding
    end
  } bind def

  /FindResource      % <name> FindResource <dict>
  { currentglobal exch                               % bGlobal /InstName
    true setglobal
    dup //.MakeInstance exec                         % bGlobal /InstName <Inst>
    DefineResource                                   % bGlobal <Inst>
    exch setglobal                                   % <Inst>
  } bind def

currentdict end
/CIDDecoding exch /Category defineresource pop

setglobal
.setlanguagelevel
